/** * QuickUML; A simple UML tool that demonstrates one use of the Java Diagram Package Copyright (C) 2001 Eric Crahen <crahen@cse.buffalo.edu> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package uml.builder; import java.util.Iterator; import java.util.StringTokenizer; import java.util.Vector; import util.WrappedIterator; /** * @class MetaMethod * * @date 08-20-2001 * @author Eric Crahen * @version 1.0 * * This class represents a methods contract - its name, its parameters, return type * and its exceptions. * */ public class MetaMethod extends MetaAttribute { private NamingComponent parameterNamingComponent = new NamingComponent(); private Vector params; private Vector exceptions; public MetaMethod(String description) { parseMethod(description); if(getName() == null) throw new SyntaxException("Invalid method descriptor"); } protected void parseMethod(String description) { // Find the parameters int m = -1, n = description.indexOf('('); if(n > 0) m = description.indexOf(')', n); if(n < 1 || m < n) throw new SyntaxException("Invalid method descriptor"); // Get the access modifiers, type & name parseAttribute(description.substring(0,n)); // Get the parameters if((m - n) > 1) parseParameters(description.substring(n+1, m)); // Check for a throws clause, skip over leading whitespace int len = description.length(); while((m+1) < len && Character.isWhitespace(description.charAt(++m))); // Check for the throws keyword char[] z = {'t', 'h', 'r', 'o', 'w', 's', ' '}; int x=0; while(m < len && x < z.length) if(z[x++] != Character.toLowerCase(description.charAt(m++))) break; // Found the keyoword, look at the final clause if(x == z.length) parseExceptions(description.substring(m)); // Last chance to validate the name checkMethod(); } /** * Last changes to the parse name can be made here. * */ protected void checkMethod() { if(getName() == null) { setName(getType()); setType("void"); } } protected void parseParameters(String description) { StringTokenizer tok = new StringTokenizer(description, ",\f"); while(tok.hasMoreTokens()) addParameter(new MetaParameter(tok.nextToken())); } /** * Add a parameter to this MetaMethod * * @param MetaParameter */ public void addParameter(MetaParameter param) { if(params == null) params = new Vector(); params.add(param); getNamingComponent().nameComponent(param); } /** * Get a component that can be used to create names for the collection * of parameters. * * @return NamingComponent */ protected NamingComponent getNamingComponent() { return parameterNamingComponent; } /** * Parse the exception list, compress the list of exceptions to eliminate duplicates */ protected void parseExceptions(String description) { StringTokenizer tok = new StringTokenizer(description, ", \f\t\r\n"); while(tok.hasMoreTokens()) { String s = tok.nextToken(); if(exceptions != null && exceptions.contains(s)) continue; if(exceptions == null) exceptions = new Vector(); exceptions.add(s); } } public boolean hasExceptions() { return exceptions != null; } public Iterator getExceptions() { return getExceptions(true); } protected Iterator getExceptions(boolean readOnly) { return new WrappedIterator(exceptions == null ? null : exceptions.iterator(), readOnly); } public boolean hasParameters() { return params != null; } public Iterator getParameters() { return getParameters(true); } protected Iterator getParameters(boolean readOnly) { return new WrappedIterator(params == null ? null : params.iterator(), readOnly); } /** * Compare by name & parameter list */ public int compareTo(Object o) { int result = -1; if(o instanceof MetaMethod) { MetaMethod m = (MetaMethod)o; // Name must match, null names count if((result = m.getName().compareTo(getName())) != 0) return result; // Parameter count must match int n = params != null ? params.size() : 0; if(n == (m.params != null ? m.params.size() : 0)) { // Compare parameters while(--n >= 0 && result == 0) { MetaParameter p1 = (MetaParameter)params.elementAt(n); MetaParameter p2 = (MetaParameter)m.params.elementAt(n); result = p1.compareTo(p2); } } else result = -1; } return result; } public String toString() { StringBuffer buf = new StringBuffer(super.toString()); buf.append('('); // Build the parameter list if(hasParameters()) { int n = 0; for(Iterator i = getParameters(); i.hasNext();) { if(n++ > 0) buf.append(", "); buf.append(i.next()); } } buf.append(')'); // Build the exception list if(hasExceptions()) { int n = 0; for(Iterator i = getExceptions(); i.hasNext();) buf.append((n++ > 0) ? ", " : " throws ").append(i.next()); } return buf.toString(); } }